import React from 'react';
import ReactDOM from 'react-dom/client';
import { Button, Tooltip, Empty, Spin, Popover } from 'antd';
import { ExportOutlined } from '@ant-design/icons';
import _ from 'lodash'

import './Luckysheet.css';

import FillEnvChooser from './FillEnvChooser'
import FillSeqChooser from './FillSeqChooser'
import FillRealChooser from './FillRealChooser'

import { RenderHelper, parseHolder } from '../core/fill'
import { exportExcel } from '../util/export'
import { SheetUtil } from '../util/utils'


const luckysheet = window.luckysheet;

let popoverRoot;

class HolderPopover extends React.Component {
  constructor(props) {
    super(props);

    this.onOpenChange = this.onOpenChange.bind(this);

    this.state = { content: null };
  }

  componentDidMount() {
    this.props.holder.getDesc().then((desc) => {
      this.setState({ content: desc });
    }).catch(err => {
      console.log('Got desc fail', err);
      this.setState({ content: err.toString() });
    });
  }

  onOpenChange(open) {
    if (!open) {
      HolderPopover.destroy();
    }
  }

  render() {
    const { holder, position } = this.props;
    const { start_r, start_c, end_r, end_c } = position;
    const content = this.state.content || (<Spin />);

    // div的位置要和选中的单元格位置重合，以便显示popover
    // 计算位置时要加上header的大小，参考luckysheet src/store/index.js
    // const rowHeaderWidth = 46;
    // const columnHeaderHeight = 20;
    const divCss = {
      position: 'absolute',
      top: start_r + 'px',
      left: start_c + 'px',
      height: (end_r - start_r) + 'px',
      width: (end_c - start_c) + 'px',
    }
    return (
      <Popover
        overlayClassName='holder-popover'
        content={content} title={holder.title}
        defaultOpen={true}
        onOpenChange={this.onOpenChange}>
        <div className='holder-cell' ref={this.divRef} style={divCss} />
      </Popover>
    )
  }
}

HolderPopover.destroy = () => {
  popoverRoot.unmount();
  popoverRoot = undefined;
}

HolderPopover.show = (holder, position, ctx) => {
  if (popoverRoot) {
    HolderPopover.destroy();
  }

  // const canvas = ctx.canvas;
  // const parent = canvas.parentElement;
  const parent = document.getElementById('luckysheet-cell-main');
  let container = parent.querySelector('.holder-cell-container');
  // .holder-cell-container与#luckysheet-cell-main完全重合
  if (!container) {
    container = document.createElement('div');
    container.className = 'holder-cell-container';
    parent.appendChild(container);
  }

  let root = ReactDOM.createRoot(container);
  popoverRoot = root;
  root.render(<HolderPopover holder={holder} position={position} />)
}

class Luckysheet extends React.Component {
  constructor(props) {
    super(props);

    this.showfillEnvChooser = this.showfillEnvChooser.bind(this);
    this.hidefillEnvChooser = this.hidefillEnvChooser.bind(this);
    this.showFillSeqChooser = this.showFillSeqChooser.bind(this);
    this.hideFillSeqChooser = this.hideFillSeqChooser.bind(this);
    this.showfillRealChooser = this.showfillRealChooser.bind(this);
    this.hidefillRealChooser = this.hidefillRealChooser.bind(this);
    this.exportWorkbook = this.exportWorkbook.bind(this);
    // this.created = false;

    this.state = {
      fillEnvChooserOpen: false,
      FillSeqChooserOpen: false,
      fillRealChooserOpen: false,
      loading: false,
    }

    this.renderHelper = null; // 报表渲染工具

    const self = this;
    self.selectedHolder = null;
    this.defaultOptions = {
      container: "luckysheet",
      lang: 'zh', // 国际化设置，允许设置表格的语言，支持简体中文("zh")、英文("en")、繁体中文("zh_tw")和西班牙文("es")
      plugins: ['chart'],
      // fontList: [
      //     { "fontName": "鸿蒙", "url": HarmonyOSTTF },
      //     {"fontName": "Pacifico", "url": PacificoTTF}
      // ],
      showinfobar: false,
      showtoolbar: true, // 默认就是true，可以不设置
      showtoolbarConfig: {
        // image: false,
        print: false,
      },
      hook: {
        updated: function (operate) {
          // console.info('workbook updated', operate);
          self.props.onChange && self.props.onChange();
        },
        cellMousedown: function (cell, position, sheet, ctx) {
          // console.info('cellMousedown', cell, position, sheet, ctx);
          const v = luckysheet.getCellValue(position.r, position.c);
          const { holder } = parseHolder(v);
          if (holder) {
            if (self.selectedHolder === v) {
              // nothing to do
            } else {
              self.selectedHolder = v;
              HolderPopover.show(holder, position, ctx);
            }
          }
          return true;
        },
        workbookCreateAfter: function (book) {
          console.info('workbookCreateAfter', book);
          self.selectedHolder = null;
          if (_.isFunction(book.data.afterWorkbookCreated)) {
            book.data.afterWorkbookCreated();
            delete book.data.afterWorkbookCreated;
          }
        },
      }
    };
  }

  buildLuckySheet(options) {
    var opt = { ...this.defaultOptions, ...options };
    console.log('create lucky sheet', opt);
    luckysheet.create(opt);
  }

  componentDidMount() {
    if (this.props.report && this.props.content) {
      const options = {
        data: this.props.content.data,
        title: this.props.report.report_name
      };
      this.buildLuckySheet(options);
    }
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    const prevData = prevProps.content && prevProps.content.data;
    const data = this.props.content && this.props.content.data;
    if (prevData !== data) {
      if (data) {
        const options = {
          data: data,
          title: this.props.report.report_name
        };
        this.buildLuckySheet(options);
      } else {
        luckysheet.destroy();
      }
    }
  }

  showfillEnvChooser() {
    this.setState({ fillEnvChooserOpen: true });
  }
  hidefillEnvChooser() {
    this.setState({ fillEnvChooserOpen: false });
  }
  showFillSeqChooser() {
    this.setState({ FillSeqChooserOpen: true });
  }
  hideFillSeqChooser() {
    this.setState({ FillSeqChooserOpen: false });
  }
  showfillRealChooser() {
    this.setState({ fillRealChooserOpen: true });
  }
  hidefillRealChooser() {
    this.setState({ fillRealChooserOpen: false });
  }

  render() {
    const { report, content, allowExport } = this.props;
    const state = this.state;
    const container = (
      <div className='sheet_container'>
        <div className='sheet_info_detail'>
          <div className='sheet_name'>
            {report && report.report_name}
          </div>
          {allowExport && <Tooltip title="导出">
            <Button
              shape="circle"
              icon={<ExportOutlined />}
              onClick={this.exportWorkbook} />
          </Tooltip>}
        </div>
        <div id="luckysheet"></div>
      </div>
    );
    return (
      <div className='sheet-wrapper'>
        <Spin spinning={state.loading}>
          {report ? container : <Empty description={"请选择文件打开"} />}
        </Spin>

        <FillEnvChooser
          config={content && content.config}
          open={state.fillEnvChooserOpen}
          onCancel={this.hidefillEnvChooser}
          onComplete={this.hidefillEnvChooser}
        />
        {state.FillSeqChooserOpen &&
          <FillSeqChooser
            config={content && content.config}
            open={state.FillSeqChooserOpen}
            onCancel={this.hideFillSeqChooser}
            onComplete={this.hideFillSeqChooser} />}
        {state.fillRealChooserOpen &&
          <FillRealChooser
            config={content && content.config}
            open={state.fillRealChooserOpen}
            onCancel={this.hidefillRealChooser}
            onComplete={this.hidefillRealChooser} />}
      </div>
    )
  }

  renderTemplate(report, content, userValues, renderComplete) {
    this.setState({ loading: true });

    const render = new RenderHelper(luckysheet, content, userValues);
    const pureContent = render.getPureContent();
    this.renderHelper = render;
    pureContent.data.afterWorkbookCreated = async () => {
      console.log('render holders');
      await render.render();
      this.setState({ loading: false });

      renderComplete && renderComplete();
    };
    return pureContent;
  }

  exportWorkbook() {
    const renderDate = this.renderHelper && this.renderHelper.renderDate;
    const sheets = luckysheet.getAllSheets();
    let fileName = this.props.report.report_name;
    if (renderDate) {
      fileName += renderDate.format('YYYYMMDD');
    }
    exportExcel(sheets, fileName);
  }

  exportTemplate() {
    const sheets = luckysheet.getAllSheets();
    const sheets2 = _.cloneDeep(sheets);

    // 将单元格格式保存在JSON字符串中，否则格式会丢失
    sheets2.forEach(s => {
      s.data.forEach(function (row, rowid) {
        row.forEach(function (cell, columnid) {
          const v = cell && cell.v;
          const { holder, cellJson } = parseHolder(v);
          if (holder && cellJson) {
            cellJson.ct = cell.ct;
            cell.v = JSON.stringify(cellJson);
          }

        });
      });
    });

    // 新增一个隐藏sheet保存config信息
    const config = this.props.content.config;
    const configSheet = {
      "name": "_config_",
      "color": "",
      "index": sheets2.length,
      "hide": 1,
      "order": sheets2.length,
      "data": [
        [{
          ct: { fa: "General", t: "g" },
          v: JSON.stringify(config),
        }]
      ],
    }
    sheets2.push(configSheet);

    exportExcel(sheets2, this.props.report.report_name);
  }
  importTemplate(options) {
    console.log('importTemplate', options);

    const sheets = options.data;
    let config;
    // 解析config数据
    if (sheets.at(-1).name === "_config_") {
      const configSheet = sheets.pop();
      const v = configSheet.celldata[0].v;
      const value = SheetUtil.getCellValue(v);
      config = JSON.parse(value);
    }

    // 解析JSON中保存的ct信息
    sheets.forEach(s => {
      s.celldata.forEach(function (cell, columnid) {

        const { v } = cell;
        const value = SheetUtil.getCellValue(v);
        const { cellJson } = parseHolder(value);
        if (cellJson && cellJson.ct) {
          v.ct = cellJson.ct;
          delete cellJson.ct;
          v.v = JSON.stringify(cellJson);
        }
      });
    });
    this.buildLuckySheet(options);

    return config;
  }

  insertEnvFill() {
    this.showfillEnvChooser();
  }
  insertSeqFill() {
    this.showFillSeqChooser();
  }
  insertRealFill() {
    this.showfillRealChooser();
  }
}

export default Luckysheet